<template>
  <div>
    <h1>自定义节点</h1>
    <div>
      <h3>
        <el-link type="primary" href="https://x6.antv.vision/zh/docs/tutorial/intermediate/custom-node" target="_blank">使用文档</el-link>
      </h3>
    </div>
    <el-button type="" @click="addCustom1">自定义节点1</el-button>
    <el-button type="" @click="addCustom2">自定义节点2</el-button>

    <div id="container6">
    </div>
  </div>
</template>

<script>
import dataObj from "@/mock/baseData.js";

import { Graph, Node, Shape } from "@antv/x6";
export default {
  data() {
    return {
      graph: "",
    };
  },
  mounted() {
    this.init();
    this.custom1();
    this.custom2();
  },
  methods: {
    custom1() {
      console.log("Shape.Rect", Shape.Rect);

      console.log("自定义节点方法1 custom1");
      console.log("三步法原则");
      try {
        // 取消注册路由。
        console.log("第一步：继承");
        class redRect extends Shape.Rect {}

        console.log("第二步：配置");
        redRect.config({
          width: 100,
          height: 40,
          markup: [
            {
              tagName: "rect",
              selector: "body",
            },
            {
              tagName: "text",
              selector: "label",
            },
          ],
          attrs: {
            body: {
              fill: "#ffffff",
              stroke: "#333333",
              strokeWidth: 2,
            },
            label: {
              fontSize: 14,
              fill: "#333333",
              refX: "50%",
              refY: "50%",
              textAnchor: "middle",
              textVerticalAnchor: "middle",
            },
          },
          // 通过钩子将自定义选项 label 应用到 'attrs/text/text' 属性上
          propHooks(metadata) {
            const { label, ...others } = metadata;
            if (label) {
              ObjectExt.setByPath(others, "attrs/text/text", label);
            }
            return others;
          },
        });
        console.log("第三步：注册");

        Graph.registerNode("redRect", redRect);
      } catch (error) {
        console.log("error", error);
      }

      console.log("添加自定义节点");
      this.graph.addNode({
        shape: "redRect",
        label: "redRect",
        x: 30,
        y: 40,
      });
    },
    addCustom1() {
      this.graph.addNode({
        shape: "redRect",
        label: "redRect",
        x: 30,
        y: 40,
      });
    },
    custom2() {
      try {
        Graph.registerNode("bigRect", {
          inherit: "rect", // 继承方形
          width: 200,
          height: 140,
          markup: [
            {
              tagName: "rect",
              selector: "body",
            },
            {
              tagName: "text",
              selector: "label",
            },
          ],
          attrs: {
            body: {
              stroke: "#e3e3e3",
              rx: 10, // 圆角矩形
              ry: 10,
              strokeWidth: 2,
              fill: "#e3e3e3",
              stroke: "#5755a1",
            },
            label: {
              // text: "big_Rect",
              fill: "#fff",
              fontSize: 18,
              // refX: 10, // x 轴偏移，类似 css 中的 margin-left
              textAnchor: "left", // 左对齐
            },
          },
        });
      } catch (error) {}
    },
    addCustom2() {
      this.graph.addNode({
        x: 100,
        y: 60,
        shape: "bigRect",
        label: "big_Rect",
        // label: 'My Custom Rect', // label 继承于基类的自定义选项
      });
    },
    init() {
      let width = document.body.clientWidth; //网页可见区域宽：
      let height = document.body.clientHeight; //网页可见区域高：
      // 渲染画布
      const graph = new Graph({
        container: document.getElementById("container6"),
        width,
        height: 900,
        panning: {
          enabled: true, //画布可以平移
          //还可以配置 eventTypes 来设置触发画布拖拽的行为，支持 leftMouseDown、 rightMouseDown、mouseWheel，默认为 ['leftMouseDown'] 。
          eventTypes: ["leftMouseDown", "rightMouseDown", "mouseWheel"],
        },

        background: {
          color: "#fffbe6", // 设置画布背景颜色
        },
        grid: {
          size: 10, // 网格大小 10px
          visible: true, // 渲染网格背景
        },
      });
      graph.fromJSON(dataObj);
      graph.centerContent(); //内容居中
      this.graph = graph;
      this.clickAction(); //系统事件
      this.custoAction(); //自定义事件
      this.addDelChangeAction(); //监听添加删除改变事件
    },
    clickAction() {
      this.graph.on("cell:click", ({ e, x, y, cell, view }) => {
        console.log("cell 节点/边:click", e, x, y, cell, view);
      });
      this.graph.on("node:click", ({ e, x, y, node, view }) => {
        console.log("node 节点:click", e, x, y, node, view);
      });
      this.graph.on("edge:click", ({ e, x, y, edge, view }) => {
        console.log("	edge 边:click", e, x, y, edge, view);
      });
      this.graph.on("blank:click", ({ e, x, y }) => {
        console.log("blank 画布空白区域:click", e, x, y);
      });
    },
    custoAction() {
      //自定义事件
      this.graph.on("node:delete", ({ view, e }) => {
        console.log("view, e ", view, e);
        e.stopPropagation();
        view.cell.remove();
      });
      this.graph.on("node:customevent", ({ name, view, e }) => {
        console.log("name, view, e ", name, view, e);
        if (name === "del_me") {
          e.stopPropagation();
          view.cell.remove();
        }
      });
    },
    addDelChangeAction() {
      //监听添加删除改变事件
      this.graph.on("node:added", ({ node, index, options }) => {
        console.log("node:added  node, index, options", node, index, options);
      });
      this.graph.on("node:removed", ({ node, index, options }) => {
        console.log("node:removed  node, index, options", node, index, options);
      });
      this.graph.on("node:changed", ({ node, options }) => {
        console.log("node:changed  node,  options", node, options);
      });

      this.graph.on("edge:added", ({ edge, index, options }) => {
        console.log("edge:added  edge, index, options", edge, index, options);
      });
      this.graph.on("edge:removed", ({ edge, index, options }) => {
        console.log("edge:removed  edge, index, options", edge, index, options);
      });
      this.graph.on("edge:changed", ({ edge, options }) => {
        console.log("edge:changed  edge,  options", edge, options);
      });
    },
  },
};
</script>

<style lang="scss" scoped>
#container6 {
  width: 100%;
  height: 500px;
}
</style>